﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace SharpGen.TemplateInterface
{
    public class CodeWriter : StreamWriter
    {
        bool sameLine = true;

        private int _level = 0;
        #region public int Level
        /// <summary>
        /// Get/Sets the Level of the CodeWriter
        /// </summary>
        /// <value></value>
        public int Level
        {
            get { return _level; }
            set { _level = value; }
        }
        #endregion

        #region public CodeWriter(string path)
        /// <summary>
        /// Initializes a new instance of the <b>CodeWriter</b> class.
        /// </summary>
        /// <param name="path"></param>
        public CodeWriter(string path)
            : base(path)
        {

        }
        #endregion

        #region public CodeWriter(Stream stream)
        /// <summary>
        /// Initializes a new instance of the <b>CodeWriter</b> class.
        /// </summary>
        /// <param name="stream"></param>
        public CodeWriter(Stream stream)
            : base(stream)
        {

        }
        #endregion

        #region public CodeWriter(string path, bool append)
        /// <summary>
        /// Initializes a new instance of the <b>CodeWriter</b> class.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="append"></param>
        public CodeWriter(string path, bool append)
            : base(path, append)
        {

        }
        #endregion

        #region private string Tabs
        /// <summary>
        /// Gets the Tabs of the CodeWriter
        /// </summary>
        /// <value></value>
        private string Tabs
        {
            get
            {
                string tabs = string.Empty;
                for (int i = 0; i < _level; i++)
                {
                    tabs += "\t";
                }
                return tabs;
            }
        }
        #endregion

        #region public void WriteBegin()
        /// <summary>
        /// 
        /// </summary>
        public void WriteBegin()
        {
            base.WriteLine(Tabs + "{");
            _level += 1;
        }
        #endregion

        #region public void WriteEnd()
        /// <summary>
        /// 
        /// </summary>
        public void WriteEnd()
        {
            if (_level > 0)
            {
                _level -= 1;
            }
            base.WriteLine(Tabs + "}");
            if (_level == 1 || _level == 2)
            {
                base.WriteLine();
            }
        }
        #endregion

        #region public override void WriteLine(string value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void WriteLine(string value)
        {
            if (sameLine)
            {
                base.WriteLine(value);
            }
            else
            {
                base.WriteLine(Tabs + value);
            }
            sameLine = false;
        }
        #endregion

        #region public override void WriteLine(string format, object arg0)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg0"></param>
        public override void WriteLine(string format, object arg0)
        {
            if (sameLine)
            {
                base.WriteLine(string.Format(format, arg0));
            }
            else
            {
                base.WriteLine(Tabs + string.Format(format, arg0));
            }
            sameLine = false;
        }
        #endregion

        #region public override void WriteLine(string format, object arg0, object arg1)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg0"></param>
        /// <param name="arg1"></param>
        public override void WriteLine(string format, object arg0, object arg1)
        {
            if (sameLine)
            {
                base.WriteLine(string.Format(format, arg0, arg1));
            }
            else
            {
                base.WriteLine(Tabs + string.Format(format, arg0, arg1));
            }
            sameLine = false;
        }
        #endregion

        #region public override void WriteLine(string format, object arg0, object arg1, object arg2)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg0"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        public override void WriteLine(string format, object arg0, object arg1, object arg2)
        {
            if (sameLine)
            {
                base.WriteLine(string.Format(format, arg0, arg1, arg2));
            }
            else
            {
                base.WriteLine(Tabs + string.Format(format, arg0, arg1, arg2));
            }
            sameLine = false;
        }
        #endregion

        #region public override void WriteLine(string format, params object[] arg)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg"></param>
        public override void WriteLine(string format, params object[] arg)
        {
            if (sameLine)
            {
                base.WriteLine(string.Format(format, arg));
            }
            else
            {
                base.WriteLine(Tabs + string.Format(format, arg));
            }
            sameLine = false;
        }
        #endregion

        #region public override void Write(string value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(string value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                base.Write(Tabs + value);
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(bool value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(bool value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(char value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(char value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(decimal value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(decimal value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(double value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(double value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(float value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(float value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(int value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(int value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(long value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(long value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(object value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(object value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(string format, object arg0)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg0"></param>
        public override void Write(string format, object arg0)
        {
            if (sameLine)
            {
                base.Write(format, arg0);
            }
            else
            {
                Write(Tabs + string.Format(format, arg0));
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(string format, object arg0, object arg1)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg0"></param>
        /// <param name="arg1"></param>
        public override void Write(string format, object arg0, object arg1)
        {
            if (sameLine)
            {
                base.Write(format, arg0, arg1);
            }
            else
            {
                Write(Tabs + string.Format(format, arg0, arg1));
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(string format, object arg0, object arg1, object arg2)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg0"></param>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        public override void Write(string format, object arg0, object arg1, object arg2)
        {
            if (sameLine)
            {
                base.Write(format, arg0, arg1, arg2);
            }
            else
            {
                Write(Tabs + string.Format(format, arg0, arg1, arg2));
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(uint value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(uint value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(string format, params object[] arg)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <param name="arg"></param>
        public override void Write(string format, params object[] arg)
        {
            if (sameLine)
            {
                base.Write(format, arg);
            }
            else
            {
                Write(Tabs + string.Format(format, arg));
            }
            sameLine = true;
        }
        #endregion

        #region public override void Write(ulong value)
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        public override void Write(ulong value)
        {
            if (sameLine)
            {
                base.Write(value);
            }
            else
            {
                Write(Tabs + value.ToString());
            }
            sameLine = true;
        }
        #endregion

        #region public override Encoding Encoding
        /// <summary>
        /// Gets the Encoding of the CodeWriter
        /// </summary>
        /// <value></value>
        public override Encoding Encoding
        {
            get { return Encoding.UTF8; }
        }
        #endregion
    }
}
